home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Aktuell
/
Amiga Aktuell.iso
/
amiga-aktuell
/
net tools
/
tcp tools
/
dl
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-09-05
|
8KB
|
329 lines
/* Copyright (C) 1995, 1996 Zlatko Calusic <maverick@fly.cc.fer.hr>
This file is part of DownLoad, FTP Client
The DownLoad is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation.
The DownLoad is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
the DownLoad source; see the file COPYING. If not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "dl.h"
/* Global variables */
int logfd, master, control, data, local; /* file descriptors */
int retry, nofatal; /* REST */
int foreground, customlog, parsed, input, aborted; /* flags */
int wildcard, cretry = MAXRETRY, custompass=0, customlogin=0;
char url[1024], host[256], path[1024], file[256];
char localhost[256], localaddr[4]; /* essential data */
char username[16], passwd[256], logfile[256], inputfile[256];
char login[16];
char buffer[BUFFER], *matching;
struct hostent *hptr;
struct sockaddr_in data_in;
int addrlen;
fd_set fdset;
struct timeval ttimer;
struct stat statbuf;
extern char *optarg; /* getopt's globals */
extern int optind, opterr, optopt;
void fperror(char *string)
{
perror(string);
fputs("Aborting download ...\n", stderr);
exit(-1);
}
void fatal(char *string)
{
puts(string);
exit(-1);
}
int getlocalhost(void)
{
char string[256];
#ifdef AMIGA
if(strcpy(localhost,getenv("HOSTNAME")))
return OK;
return ERROR;
#else
if (!gethostname(localhost, 256))
{
if (!strchr(localhost, '.') && !getdomainname(string, 256) && string[0])
{
strcat(localhost, ".");
strcat(localhost, string);
}
return OK;
}
else
return ERROR;
#endif
}
void initialize(int argc, char **argv)
{
char ch, *cptr;
int printed = 0, usage = 0;
strcpy(login,"anonymous");
while ((ch = getopt(argc, argv, "fl:i:r:n:p:h")) != EOF)
switch (ch)
{
case 'f':
foreground++;
break;
case 'l':
customlog++;
strcpy(logfile, optarg);
break;
case 'i':
input++;
strcpy(inputfile, optarg);
break;
case 'r':
if ((cretry = atoi(optarg)) <= 0)
{
printf("Retry count invalid, setting to %d.\n", MAXRETRY);
cretry = MAXRETRY;
printed = 1;
}
else if (cretry > 500)
{
puts("Retry count too big, setting to 500.");
cretry = 500;
printed = 1;
}
break;
case 'p':
custompass++;
strcpy(passwd, optarg);
break;
case 'n':
customlogin++;
strcpy(login, optarg);
break;
case 'h':
case '?':
default:
usage++;
break;
}
if (argc == optind + 1)
strcpy(url, argv[optind]);
else if (argc == optind + 2)
{
strcpy(url, argv[optind]);
strcat(url, ":");
strcat(url, argv[optind + 1]);
}
else if (argc != optind || !input || usage)
{
#ifdef AMIGA
puts("Usage: dl [-i inputfile] [-r retrycnt] [-n login] [-p passwd] [-h] [URL]\n");
#else
puts("Usage: dl [-f] [-l logfile] [-i inputfile] [-r retrycnt] [-p passwd] [-h] [URL]\n");
#endif
puts("Command line switches:\n");
#ifndef AMIGA
puts(" -f download in the foreground");
puts(" -l logfile custom logfile name (works in the background)");
#endif
puts(" -i inputfile load URLs from the inputfile");
puts(" -r retrycnt retry count (default 50, max 500)");
#ifdef AMIGA
puts(" -p passwd custom (anonymous) password");
puts(" -n login custom login");
#else
puts(" -p passwd custom anonymous password");
#endif
puts(" -h this help\n");
puts("URL specification (wildcards are allowed):\n");
puts(" hostname:pathname");
puts(" hostname pathname");
puts(" ftp://hostname/pathname\n");
exit(0);
}
if (!printed)
printf("Retry count set to %d%s", cretry, cretry == 50 ? " (default).\n" : ".\n");
if (foreground && customlog)
puts("Ignoring -l switch, program is running in the foreground.");
if (!getlocalhost() || !(hptr = gethostbyname(localhost)))
fatal("Can't resolve local hostname, exiting ...");
memcpy(localaddr, hptr->h_addr_list[0], 4);
#ifdef AMIGA
if(!(cptr=getenv("USER")))
cptr = "unknown";
#else
if (!(cptr = cuserid(NULL)))
cptr = "unknown";
#endif
strcpy(username, cptr);
if (!custompass)
{
strcpy(passwd, cptr);
strcat(passwd, "@");
strcat(passwd, localhost);
}
printf("Using %s as %s password.\n", passwd, login);
return;
}
int main(int argc, char **argv)
{
printf("%s v%s by %s %s, %s\n", PROGRAM, VERSION, AUTHOR, EMAIL, DATE);
#ifdef AMIGA
printf("Ported to Amiga by Niksa Franceschi <nfrances@zems.fer.hr>, 24 Jul 1996\n");
#endif
sleep(1);
initialize(argc, argv);
fflush(stdout);
#ifndef AMIGA
if (!foreground)
{
int i = 0;
pid_t pid;
if (!customlog)
{
#ifdef AMIGA
sprintf(logfile, "dl_log.%s", username);
#else
sprintf(logfile, "/tmp/dl_log.%s", username);
#endif
while (stat(logfile, &statbuf) == 0) {
#ifdef AMIGA
sprintf(logfile, "dl_log.%d", ++i);
#else
sprintf(logfile, "dl_log.%s.%d", username, ++i);
#endif
}
}
if ((logfd = open(logfile, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0)
fatal("Can't open log file, exiting ...");
#ifndef AMIGA
dup2(logfd, 2);
#endif
close(logfd);
fputs("****************************************************************\n", stderr);
fprintf(stderr, "Log file generated by %s v%s\n", PROGRAM, VERSION);
fprintf(stderr, "Send bug reports to %s %s\n", AUTHOR, EMAIL);
#ifdef AMIGA
fprintf(stderr, "Ported to Amiga by Nick <nfrances@zems.fer.hr>\n");
#endif
fputs("****************************************************************\n", stderr);
printf("Log file is %s\n", logfile);
signal(SIGCLD, SIG_IGN);
switch ((pid = fork()))
{
case -1:
fatal("Fork failed, try running in the foreground ...");
case 0:
sleep(2);
setsid();
break;
default:
printf("Continuing in the background (pid %d) ...", (int) pid);
fflush(stdout);
sleep(1);
puts("\n");
exit(0);
}
}
else
dup2(1, 2);
#endif
if (!input)
download();
else
{
FILE *inputfp;
if (!(inputfp = fopen(inputfile, "r")))
{
fputs("Can't open input file, exiting ...\n", stderr);
exit(-1);
}
if (argc == optind + 1)
download();
while (fgets(url, 256, inputfp))
{
char *cptr;
if ((cptr = strchr(url, '\n')))
*cptr = 0;
download();
}
fclose(inputfp);
}
exit(0);
}
int download(void)
{
char *current;
aborted = parsed = wildcard = 0;
current = NULL;
fprintf(stderr, "\nDOWNLOAD -> [%s]\n", url);
for (retry = 1; retry <= cretry; retry++)
{
if (aborted)
return ERROR;
if (!parsed && !parse())
{
fputs("Error parsing hostname and/or pathname, aborting ...\n", stderr);
return ERROR;
}
sleep(5);
fputc('\n', stderr);
if (!establish_connection())
continue;
if (!ftprequest("USER %s\r\n", login) || !ftprequest("PASS %s\r\n", passwd))
continue;
if (*path)
if (!ftprequest("CWD %s\r\n", path))
continue;
if (!wildcard && (strchr(file, '*') || strchr(file, '?') || strchr(file, '[')) && !get_list())
continue;
if (!ftprequest("TYPE I\r\n", NULL))
continue;
next_file:
if (!retrieve_file())
continue;
if (wildcard && (current = strtok(NULL, "\r")))
{
strcpy(file, current);
retry = 1;
goto next_file;
}
ftprequest("QUIT\r\n", NULL);
return OK;
}
fprintf(stderr, "Maximum retry count reached (%d), aborting ...\n", cretry);
return ERROR;
}